﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Kokomo.Mirror.CliMetadata.Signatures
{
	class PointerTypeSpec : SyntheticTypeSpec
	{
		public override Type ResolveType(
			Module module,
			bool throwOnError,
			Type[] genericTypeArgs,
			Type[] genericMethodArgs
			)
		{
			Type elementType = (this.type == null)
				? typeof(void)
				: this.type.ResolveType(module, throwOnError, genericTypeArgs, genericMethodArgs)
				;

			if ((object)elementType == null)
			{
				if (throwOnError)
					throw new TypeLoadException();
				else
					return null;
			}
			Type pointerType = elementType.MakePointerType();

			return pointerType;
		}

		public override bool Matches(
			Type type,
			Module module,
			Type[] genericTypeArguments,
			Type[] genericMethodArguments
			)
		{
			if ((object)type == null) throw new ArgumentNullException("type");

			if (!type.IsPointer) return false;

			bool matches =
				this.type.Matches(type.GetElementType(), module, genericTypeArguments, genericMethodArguments)
				;
			return matches;
		}

		public override string ToString()
		{
			return this.type.ToString() + "*";
		}

		public override bool Equals(object obj)
		{
			PointerTypeSpec other = obj as PointerTypeSpec;
			if (other == null) return false;

			bool equals = object.Equals(this.type, other.type);
			return equals;
		}
		public override bool Matches(
			Module ownerModule,
			TypeSpec other,
			Module otherModule
			)
		{
			if ((object)ownerModule == null) throw new ArgumentNullException("ownerModule");
			if (other == null) throw new ArgumentNullException("other");
			if ((object)otherModule == null) throw new ArgumentNullException("otherModule");

			PointerTypeSpec otherPointer = other as PointerTypeSpec;
			if (otherPointer == null) return false;

			bool matches =
				this.type.Matches(ownerModule, otherPointer.type, otherModule)
				;

			return matches;
		}
	}
}
